<!doctype html>
<html>
    <head>
        <title>HT for Web 属性组件手册</title>
        <meta charset="UTF-8">    
        <meta name="viewport" content="user-scalable=yes, width=1024">
        <style type="text/css"> 
            h1, h2, h3, h4, h5, h6, p, blockquote {
                margin: 0;
                padding: 0;
            }
            body {
                font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
                font-size: 13px;
                line-height: 18px;
                color: #737373;
                background-color: white; 
                margin: 10px 13px 10px 13px;
            }
            table {
                margin: 10px 0 15px 0;
                border-collapse: collapse;
            }
            td,th {	
                border: 1px solid #ddd;
                padding: 3px 10px;
            }
            th {
                padding: 5px 10px;	
            }
            a {
                color: #0069d6;
            }
            a:hover {
                color: #0050a3;
                text-decoration: none;
            }
            a img {
                border: none;
            }
            p {
                margin-bottom: 9px;
            }
            h1, h2, h3, h4, h5, h6 {
                color: #404040;
                line-height: 36px;
            }
            h1 {
                margin-bottom: 18px;
                font-size: 30px;
            }
            h2 {
                font-size: 24px;
            }
            h3 {
                font-size: 18px;
            }
            h4 {
                font-size: 16px;
            }
            h5 {
                font-size: 14px;
            }
            h6 {
                font-size: 13px;
            }
            hr {
                margin: 0 0 19px;
                border: 0;
                border-bottom: 1px solid #ccc;
            }
            blockquote {
                padding: 13px 13px 21px 15px;
                margin-bottom: 18px;
                font-family:georgia,serif;
                font-style: italic;
            }
            blockquote:before {
                content:"\201C";
                font-size:40px;
                margin-left:-10px;
                font-family:georgia,serif;
                color:#eee;
            }
            blockquote p {
                font-size: 14px;
                font-weight: 300;
                line-height: 18px;
                margin-bottom: 0;
                font-style: italic;
            }
            code, pre {
                font-family: Monaco, Andale Mono, Courier New, monospace;
            }
            code {
                background-color: #fee9cc;
                color: rgba(0, 0, 0, 0.75);
                padding: 1px 3px;
                font-size: 12px;
                -webkit-border-radius: 3px;
                -moz-border-radius: 3px;
                border-radius: 3px;
            }
            pre {
                display: block;
                padding: 14px;
                margin: 0 0 18px;
                line-height: 16px;
                font-size: 11px;
                border: 1px solid #d9d9d9;
                white-space: pre-wrap;
                word-wrap: break-word;
            }
            pre code {
                background-color: #fff;
                color:#737373;
                font-size: 11px;
                padding: 0;
            }
            sup {
                font-size: 0.83em;
                vertical-align: super;
                line-height: 0;
            }
            * {
                -webkit-print-color-adjust: exact;
            }
            @media screen and (min-width: 914px) {
                body {
                    width: 854px;
                    margin:10px auto;
                }
            }
            @media print {
                body,code,pre code,h1,h2,h3,h4,h5,h6 {
                    color: black;
                }
                table, pre {
                    page-break-inside: avoid;
                }
            }                        
            iframe{
                width: 100%;
                border: 1px solid #34495E;
                margin: 0;                
            }            
            .logo{
                vertical-align: middle;
            }

        </style>        
        <script>
            function init() {
                var logoSrc = '',
                    logos = document.querySelectorAll('.logo'),
                    i = 0;
                for (; i < logos.length; i++) {
                    logos[i].src = logoSrc;
                }
                
                var iframes = document.querySelectorAll('iframe'),
                    func = function(){};
                for (i=0; i < iframes.length; i++) {
                    var iframe = iframes[i];
                    
                    // a small hack to make it work on android
                    iframe.ontouchstart = func;
                    
                    var div = document.createElement('div');
                    div.innerHTML = '<a href="' + iframe.src + '" target="_blank">独立运行→</a>';
                    iframe.parentNode.insertBefore(div, iframe);
                }   
            }
        </script>    
    </head>
    <body onload="init();">
        <a href="http://www.hightopo.com"><img class="logo"></a>HT for Web 属性组件手册
        <hr style="margin: 1px 0 20px 0">
<p>索引</p>

<ul><li><a href="#ref_overview">概述</a></li><li><a href="#ref_property">属性</a></li><li><a href="#ref_propertyview">属性组件</a></li></ul>

<hr/>

<div id="ref_overview"></div>

<h2>概述</h2>

<p><code>HT for Web</code>提供了属性组件类<code>ht.widget.PropertyView</code>，用于显示<code>DataModel</code>数据容器中，当前选中的<code>Data</code>类型对象的属性，
支持分组、排序和过滤等方式展示属性。另外<code>ht</code>提供了<a href="../../plugin/propertypane/ht-propertypane-guide.html">属性面板插件</a>，
该扩展插件将分组、排序和过滤提供了可视化的组件封装。</p>

<p>通过<code>propertyView = new ht.widget.PropertyView(dataModel);</code>初始化构建一个属性组件对象，<code>dataModel</code>参数为属性组件绑定的数据模型，
该模型为空时属性组件构造函数内部将创建一个新的数据模型进行绑定。</p>

<p>属性组件的<code>getPropertyModel()</code>函数返回属性模型对象，其本质也是个<code>DataModel</code>类型对象，只不过该对象是仅用于添加<code>ht.Property</code>类型对象，
<code>ht.Property</code>类型的父类为<code>ht.Data</code>，增加了和属性定义相关的函数接口。</p>

<p>因此用户所需要做的工作是，根据要显示的属性信息构建出<code>ht.Property</code>对象，然后添加到<code>propertyView.getPropertyModel()</code>函数返回的属性模型，
这样当<code>propertyView.getDataModel()</code>的数据模型选中图元变化时，当前选中图元<code>Data</code>的相关属性信息，就会根据<code>propertyView.getPropertyModel()</code>
上存储的<code>ht.Property</code>对象的配置进行显示。</p>

<div id="ref_property"></div>

<h2>属性</h2>

<p><code>ht.Property</code>属性类继承于<code>ht.Data</code>，不可设置父子关系，具备以下属性函数：</p>

<ul><li><code>getName()</code>和<code>setName(name)</code>用于存取<code>name</code>属性，该属性结合<code>accessType</code>属性最终实现对<code>Data</code>属性的存取</li><li><code>getDisplayName()</code>和<code>setDisplayName(displayName)</code>用于存取属性名的显示文本值，若为空则显示<code>name</code>属性值</li><li><code>getIcon()</code>和<code>setIcon(&#39;icon&#39;)</code>存取属性名左侧显示的图标</li><li><code>getColor()</code>和<code>setColor(color)</code>存取属性名的文本颜色</li><li><code>getCategoryName</code>和<code>setCategoryName(&#39;name&#39;)</code>设置属性所在分组</li><li><code>isEditable()</code>和<code>setEditable(true/false)</code>设置该属性是否可编辑，默认为<code>false</code></li><li><code>isBatchEditable()</code>和<code>setBatchEditable(true/false)</code>设置该属性是否允许多选时批量编辑，默认为<code>true</code></li><li><code>getAccessType()</code>和<code>setAccessType(type)</code>操作存取属性类型：<ul><li><code>null</code>： 默认类型，如<code>name</code>为<code>age</code>，采用<code>getAge()</code>和<code>setAge(98)</code>的<code>get/set</code>或<code>is/set</code>方式存取</li><li><code>style</code>：如<code>name</code>为<code>age</code>，采用<code>getStyle(&#39;age&#39;)</code>和<code>setStyle(&#39;age&#39;, 98)</code>的方式存取</li><li><code>field</code>：如<code>name</code>为<code>age</code>，采用<code>data.age</code>和<code>data.age = 98</code>的方式存取</li><li><code>attr</code>：如<code>name</code>为<code>age</code>，采用<code>getAttr(&#39;age&#39;)</code>和<code>setAttr(&#39;age&#39;, 98)</code>的方式存取</li></ul></li><li><code>valueType</code>值类型用于提示组件提供合适的<code>renderer</code>渲染，合适的编辑控件，及改变值时必要的类型转换：<ul><li><code>null</code>：默认类型，显示为文本方式</li><li><code>string</code>：字符串类型，显示为文本方式</li><li><code>boolean</code>：布尔类型，显示为勾选框</li><li><code>color</code>：颜色类型，以填充背景色的方式显示</li><li><code>int</code>：整型类型，文本编辑器改变值时自动通过<code>parseInt</code>进行转换</li><li><code>number</code>：浮点数类型，文本编辑器改变值时自动通过<code>parseFloat</code>转换</li></ul></li><li><code>getAlign()</code>和<code>setAlign(&#39;left&#39;/&#39;center&#39;/&#39;right&#39;)</code>决定以文本方式进行渲染时的水平对齐方式，默认为<code>left</code></li><li><code>isNullable()</code>和<code>setNullable(true/false)</code>决定该属性是否可为空，默认为<code>true</code>，设置为<code>false</code>可避免输入<code>null</code>或<code>undefined</code></li><li><code>isEmptiable()</code>和<code>setEmptiable(true/false)</code>决定属性是否可为空字符串，默认为<code>false</code>，可避免输入空字符串，空字符串转换成<code>undefined</code></li><li><code>property.getValue = function(data, property, view){return value}</code>自定义获取值函数</li><li><code>property.setValue = function(data, property, value, view){}</code>自定义设置值函数</li><li><code>property.drawPropertyValue = function(g, property, value, rowIndex, x, y, w, h, data, view)</code>自定义属性值渲染函数</li><li><code>property.drawPropertyName = function(g, property, rowIndex, x, y, w, h, view)</code>自定义属性名渲染函数</li><li><code>property.formatValue = function(value)</code>一般用于将数字转换更易读的文本格式，可重载自定义</li><li><code>property.getToolTip = function(data, isValue, propertyView)</code>自定义文字提示内容，<code>isValue</code>代表目前鼠标是否在属性值范围，若不是则在左侧属性名</li></ul>

<p>枚举是较为常见的属性编辑选择应用，在编辑时候呈现下拉列表，因此<code>ht</code>对枚举类型属性考虑了很多应用场景，<code>setEnum(params)</code>函数即可设置单个的<code>json</code>参数，
也可以设置逐个的参数信息<code>setEnum(enumValues, enumLabels, enumIcons, enumEditable, enumStrict)</code>，
以下为常见的案例：</p>

<ul><li><code>setEnum([&#39;C&#39;,&#39;C++&#39;,&#39;JS&#39;])</code>，传递数值数组      </li><li><code>setEnum([1,2,3], [&#39;C&#39;,&#39;C++&#39;,&#39;JS&#39;])</code>，传递数值和文字数组  </li><li><code>setEnum([1,2,3], [&#39;C&#39;,&#39;C++&#39;,&#39;JS&#39;], [&#39;c_icon&#39;, &#39;c++_icon&#39;, &#39;js_icon&#39;])</code>，传递数值、文字和图标数组</li><li><code>setEnum({values:[1,2,3]})</code>，传递数值数组</li><li><code>setEnum({values:[1,2,3], labels:[&#39;C&#39;,&#39;C++&#39;,&#39;JS&#39;]})</code>，传递数值和文字数组</li><li><code>setEnum({values:[1,2,3], labels:[&#39;C&#39;,&#39;C++&#39;,&#39;JS&#39;], icons:[&#39;c_icon&#39;, &#39;c++_icon&#39;, &#39;js_icon&#39;]})</code>，传递数值、文字和图标数组</li></ul>

<blockquote><p><code>ht</code>内部会自动检测用户是否引入了<a href="../../plugin/form/ht-form-guide.html">表单插件</a>，若引入了表单插件的<code>ht.widget.ComboBox</code>组件则采用之作为编辑器，
否则采用原生<code>html</code>的<code>select</code>组件，由于原生<code>html</code>的<code>select</code>下拉组件只文本显示，因此上面的很多参数仅对<code>ht.widget.ComboBox</code>组件起作用。</p></blockquote>

<ul><li><code>enumValues</code>：枚举值数组</li><li><code>enumLabels</code>：枚举文本数组 </li><li><code>enumIcons</code>：枚举图标数组</li><li><code>enumEditable</code>：枚举下拉编辑器是否允许可输入，默认为<code>false</code></li><li><code>enumStrict</code>：值匹配时是否采用严格的<code>===</code>进行比较，默认为<code>true</code>，若为<code>false</code>则采用<code>==</code>进行比较</li></ul>

<p><a href="../../plugin/form/ht-form-guide.html">表单插件</a>中的滑动条<code>ht.widget.Slider</code>也是较为常见和易用的编辑组件，
为此<code>ht</code>也增加了该类型相应属性的设置，通过<code>getSlider()</code>和<code>setSlider(parmas)</code>可指定该属性在编辑状态呈现的滑动条信息。</p>

<p><iframe src="examples/example_property.html" style="height:250px"></iframe></p>

<div id="ref_propertyview"></div>

<h2>属性组件</h2>

<p>属性组件类<code>ht.widget.PropertyView</code>主要可配置属性和函数如下：</p>

<ul><li><code>isEditable()</code>和<code>setEditable(true/false)</code>控制可否编辑的总开关，默认为<code>true</code>，每个<code>Property</code>属性可再控制</li><li><code>isBatchEditable()</code>和<code>setBatchEditable(true/false)</code>控制可否多选时批量编辑总开关，默认为<code>true</code>，每个<code>Property</code>属性可再控制</li><li><code>isCategorizable</code>和<code>setCategorizable(true/false)</code>控制是否分组，默认为<code>true</code>，为<code>false</code>则忽略<code>Property</code>的<code>categoryName</code>属性</li><li><code>getIndent()</code>和<code>setIndent(20)</code>控制左侧缩进，左侧空间用于绘制分组<code>toggle</code>图标，以及属性提示<code>icon</code>图标</li><li><code>getSortFunc()</code>和<code>setSortFunc(func)</code>获取和设置属性排序函数</li><li><code>getVisibleFunc()</code>和<code>setVisibleFunc(func)</code>获取和设置属性过滤器，也可通过<code>PropertyView#isVisible(property)</code>函数重载</li><li><code>getExpandIcon()</code>和<code>setExpandIcon(icon)</code>获取和设置分组展开的图标。</li><li><code>getCollapseIcon()</code>和<code>setCollapseIcon(icon)</code>： 分组合并的图标。</li><li><code>getScrollBarColor()</code>和<code>setScrollBarColor(color)</code>获取和设置滚动条颜色</li><li><code>getScrollBarSize()</code>和<code>setScrollBarSize(6)</code>获取和设置滚动条宽度</li><li><code>isAutoHideScrollBar()</code>和<code>setAutoHideScrollBar(true/false)</code>获取和设置是否自动隐藏滚动条，默认为<code>true</code></li><li><code>getSelectRowIndex()</code>和<code>setSelectRowIndex(10)</code>获取和设置当前选中行索引</li><li><code>getSelectBackground(data)</code>和<code>setSelectBackground(color)</code>获取和设置行选中背景颜色</li><li><code>getBackground()</code>和<code>setBackground(color)</code>获取和设置边框和分组行的背景颜色</li><li><code>getRowHeight()</code>和<code>setRowHeight(20)</code>获取和设置行高</li><li><code>isRowLineVisible()</code>和<code>setRowLineVisible(true/false)</code>获取和设置行线是否可见，默认为<code>true</code></li><li><code>getRowLineColor()</code>和<code>setRowLineColor(color)</code>获取和设置行线颜色</li><li><code>isColumnLineVisible()</code>和<code>setColumnLineVisible(true/false)</code>获取和设置列线是否可见，默认为<code>true</code></li><li><code>getColumnLineColor()</code>和<code>setColumnLineColor(color)</code>获取和设置列线颜色</li><li><code>getColumnPosition()</code>和<code>setColumnPosition(0.5)</code>获取和设置列线位置比例，默认值<code>0.5</code>，允许范围为<code>0</code>~<code>1</code></li><li><code>getRows()</code>返回当前显示的所有行信息的数组，数组元素为<code>string</code>类型代表分组名，<code>{data:d,property:p}</code>结构对象代表属性信息</li><li><code>getPropertyName(property)</code>返回显示在左列的属性名，可重载自定义</li><li><code>getLabelFont(property, value, rowIndex)</code>返回属性值文本字体，可重载自定义</li><li><code>getLabelColor(property, value, rowIndex)</code>返回属性值文本颜色，可重载自定义</li><li><code>getPropertyFont(property, rowIndex)</code>返回属性名文本字体，可重载自定义</li><li><code>getPropertyColor(property, rowIndex)</code>返回属性名文本颜色，可重载自定义</li><li><code>getCategoryFont(categoryName)</code>返回分组文本字体，可重载自定义</li><li><code>getCategoryColor(categoryName)</code>返回分组文本颜色，可重载自定义</li><li><code>isExpanded(categoryName)</code>判断分组是否展开</li><li><code>toggle(categoryName)</code>切换分组的展开和合并</li><li><code>expandAll()</code>展开所有分组</li><li><code>expand(categoryName)</code>展开分组</li><li><code>onExpanded(categoryName)</code>展开分组时回调，可重载做后续处理</li><li><code>collapseAll()</code>合并所有分组</li><li><code>collapse(categoryName)</code>合并分组</li><li><code>onCollapsed(categoryName)</code>合并分组时回调，可重载做后续处理</li><li><code>getPropertyModel()</code>获取<code>propertyModel</code>属性，其为<code>DataModel</code>类型，可增删<code>Property</code>属性对象 </li><li><code>getDataModel()</code>和<code>setDataModel(dataModel)</code>获取和设置绑定的<code>DataModel</code>数据模型</li><li><code>updateCurrentData()</code>更新当前要显示属性的<code>Data</code>类型对象，默认为<code>SelectionModel</code>最后选中的对象</li><li><code>getCurrentData()</code>获取当前显示对象</li><li><code>drawCategoryName(g, name, rowIndex, x, y, w, h)</code>绘制分组名，可重载自定义</li><li><code>drawPropertyName(g, property, rowIndex, x, y, w, h)</code>绘制属性名，可重载自定义</li><li><code>drawPropertyValue(g, property, value, rowIndex, x, y, w, h, data)</code>绘制属性值，可重载自定义</li><li><code>isPropertyEditable(property)</code>判断属性是否可编辑，可重载自定义</li><li><code>getRawProperties()</code>返回要显示的原始未过滤排序的属性<code>ht.List</code>集合，默认返回<code>propertyModel.getRoots()</code>，可重载自定义</li><li><code>getRowIndexAt(event)</code>返回<code>event</code>事件所在的行索引</li><li><code>getPropertyAt(event)</code>返回<code>event</code>事件所在的行的属性信息</li><li><code>enableToolTip()</code>和<code>disableToolTip()</code>开启和关闭文字提示</li><li><code>isDisabled()</code>和<code>setDisabled(true/false, iconURL)</code>可获取和设置整个组件处于不可用状态</li><li><code>addTopPainter(func)</code>和<code>removeTopPainter(func)</code>增加和删除顶层绘制器<code>function(g){...}</code></li><li><code>addBottomPainter(func)</code>和<code>removeBottomPainter(func)</code>增加和删除底层绘制器<code>function(g){...}</code></li><li><code>addProperties(array)</code>用<code>json</code>的数组参数方式批量添加属性信息</li><li><code>setProperties(array)</code>用<code>json</code>的数组参数方式批量添加属性信息，参数为空时代表清空目前所有属性</li></ul>

<p><iframe src="examples/example_custom.html" style="height:260px"></iframe></p>

<p><code>PropertyView</code>提供了<code>addProperties</code>和<code>setProperties</code>的函数，可通过<code>json</code>格式较容易的批量添加<code>Property</code>属性，上例采用了如下的代码方式：</p>

<pre><code>propertyView.addProperties([
    {
        name: &#39;name&#39;,
        displayName: &#39;Name&#39;
    },
    {
        displayName: &#39;CPU&#39;,
        drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view) {
            drawFunc(g, data.a(&#39;cpu&#39;), x, y, w, h);
        },
        getToolTip: function(data, isValue, propertyView){
            return isValue ? data.a(&#39;cpu&#39;) + &#39;%&#39; : &#39;CPU usage percentage&#39;;
        }
    },
    {
        displayName: &#39;MEM&#39;,
        drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view) {
            drawFunc(g, data.a(&#39;mem&#39;), x, y, w, h);
        },
        getToolTip: function(data, isValue, propertyView){
            return isValue ? data.a(&#39;mem&#39;) + &#39;%&#39; : &#39;Memory usage percentage&#39;;
        }        
    }
]);  </code></pre>

<p>以上列子在定义<code>CPU</code>和<code>MEM</code>的<code>Property</code>时，未指定任何<code>name</code>和<code>accessType</code>的信息，因为他们都定义了drawPropertyValue函数，
因此<code>ht</code>内部无需获取值的配置信息，但这也带来了另外的问题，当<code>propertyView.enableToolTip()</code>后，<code>ht</code>内部无法获取到值信息进行提示，
因此该例子中在定义<code>CPU</code>和<code>MEM</code>的<code>Property</code>时，都定义了getToolTip函数进行自定义。</p>

<p>例子中呈现指标时当百分比值在<code>0~40</code>之间采用绿色，<code>40~70</code>之间采用黄色，<code>70~100</code>之间采用红色，因此定义了<code>getColor</code>的统一颜色转换函数，
同时<code>drawPropertyValue</code>的自定义函数也都调用了<code>drawFunc</code>的统一百分比绘制函数。</p>

<pre><code>getColor = function(value) {
    if (value &lt; 40)
        return &#39;#00A406&#39;;
    if (value &lt; 70)
        return &#39;#FFCC00&#39;;
    return &#39;#A60000&#39;;
};

drawFunc = function(g, value, x, y, w, h){
    g.fillStyle = &#39;#A1A1A3&#39;;
    g.beginPath();
    g.rect(x, y, w, h);
    g.fill();                    
    g.fillStyle = getColor(value);
    g.beginPath();
    g.rect(x, y, w * value / 100, h);
    g.fill();
    ht.Default.drawText(g, value + &#39;%&#39;, &#39;12px Arial&#39;, &#39;white&#39;, x, y, w, h, &#39;center&#39;);                
};</code></pre>    <hr id="contact" style="margin: 20px 0 1px 0">
    <a href="http://www.hightopo.com"><img class="logo"></a>欢迎交流 <a href="mailto:service@hightopo.com">service@hightopo.com</a>
</body>
</html>
